home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / CPP / BTREE.ZIP / BTREEIMP.H < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-14  |  20.3 KB  |  1,038 lines

  1. /*
  2.  * BTreeImp.h                   B+ Tree Implimentation
  3.  *
  4.  * (c) DownEast Technology, Inc., 1994
  5.  * Written by Steve Nutt
  6.  */
  7.  
  8. #if !defined(BTREEIMP_H)
  9. #define BTREEIMP_H
  10.  
  11. #if !defined(BNODE_H)
  12. #include "BNode.h"
  13. #endif
  14. //#define _DEBUG_B_TREE_ 
  15.  
  16. template <class Node, class T> class TBPlusTreeIteratorBase;
  17.  
  18. template <class Node, class T> class TBPlusTreeBase
  19. {
  20.     friend TBPlusTreeIteratorBase <Node, T>;
  21.  
  22. protected:
  23.     typedef Node::TChain TChain;
  24.  
  25. public:
  26.     typedef void (*IterFunc) (T&, void*);
  27.     typedef int (*CondFunc) (const T&, void*);
  28.     typedef int (*CompFunc) (const T&, void*);
  29.  
  30.     TBPlusTreeBase (void)
  31.         {
  32.         root = 0;
  33.         itemCnt = 0;
  34.         }
  35.  
  36.     unsigned GetItemsInContainer (void) const
  37.         {
  38.         return itemCnt;
  39.         }
  40.  
  41.     int HasMember (const T* t) const
  42.         {
  43.         return FindNode (t) != 0;
  44.         }
  45.  
  46.     int IsEmpty (void) const
  47.         {
  48.         return GetItemsInContainer() == 0;
  49.         }
  50.  
  51.     T* Last (void) const
  52.         {
  53.         return (root ? static_cast<Node*> (root->WalkRight())->DataPtr() : 0);
  54.         }
  55.  
  56.     T* First (void) const
  57.         {
  58.         return (root ? static_cast<Node*> (root->WalkLeft())->DataPtr() : 0);
  59.         }
  60.  
  61.     T* Find (const T* t) const
  62.         {
  63.         Node* node = FindNode (t);
  64.         return (node ? node->DataPtr() : 0);
  65.         }
  66.  
  67.     void Flush (void)
  68.         {
  69.         root = 0;
  70.         itemCnt = 0;
  71.         }
  72.  
  73.     void ForEach (IterFunc, void*);
  74.     T* LastThat (CondFunc, void*) const;
  75.     T* FirstThat (CondFunc, void*) const;
  76.     T* Search (CompFunc, void*) const;
  77.  
  78. protected:
  79.     int AddNode (Node*, TChain&);
  80.     void DetachNode (Node*, TChain&);
  81.     Node* FindNode (const T*) const;
  82.     Node* FindNode (const T*, TChain&);
  83.  
  84.     Node::TNodeBase* root;
  85.  
  86. private:
  87.     void BalanceAdd (TChain&);
  88.     unsigned itemCnt;
  89.  
  90. #if __DEBUG > 0
  91. #if defined(_DEBUG_B_TREE_)
  92.     void CheckValues (Node&, const T*&, const T*&);
  93. protected:
  94.     int CheckTree (void);
  95. #endif
  96. #endif
  97. };
  98.  
  99. /*
  100.  * Member function for template TBPlusTreeBase
  101.  */
  102. template <class Node, class T>
  103. void TBPlusTreeBase<Node, T>::ForEach (
  104.     IterFunc iter,
  105.     void* args)
  106. {
  107.     if (!root)
  108.         return;
  109.  
  110.     TChain chain;
  111.     chain.Push (&root);
  112.     root->WalkLeft (chain);
  113.     while (!chain.IsEmpty())
  114.     {
  115.         Node& node = *static_cast<Node*> (*chain.Top());
  116.         iter (*node.DataPtr(), args);
  117.         Node::Next (chain);
  118.     }
  119.     chain.Flush (TShouldDelete::NoDelete);
  120. }
  121.  
  122. template <class Node, class T>
  123. T* TBPlusTreeBase<Node, T>::LastThat (
  124.     CondFunc cond,
  125.     void* args) const
  126. {
  127.     if (!root)
  128.         return 0;
  129.  
  130.     TChain chain;
  131.     chain.Push (const_cast<Node::TNodeBase**> (&root));
  132.     root->WalkRight (chain);
  133.     T* data;
  134.     while (!chain.IsEmpty())
  135.     {
  136.         data = static_cast<Node*> (*chain.Top())->DataPtr();
  137.         if (cond (*data, args))
  138.             break;
  139.  
  140.         Node::Previous (chain);
  141.     }
  142.     if (chain.IsEmpty())
  143.         data = 0;
  144.  
  145.     chain.Flush (TShouldDelete::NoDelete);
  146.     return data;
  147. }
  148.  
  149. template <class Node, class T>
  150. T* TBPlusTreeBase<Node, T>::FirstThat (
  151.     CondFunc cond,
  152.     void* args) const
  153. {
  154.     if (!root)
  155.         return 0;
  156.  
  157.     TChain chain;
  158.     chain.Push (const_cast<Node::TNodeBase**> (&root));
  159.     root->WalkLeft (chain);
  160.     T* data;
  161.     while (!chain.IsEmpty())
  162.     {
  163.         data = static_cast<Node*> (*chain.Top())->DataPtr();
  164.         if (cond (*data, args))
  165.             break;
  166.  
  167.         Node::Next (chain);
  168.     }
  169.     if (chain.IsEmpty())
  170.         data = 0;
  171.  
  172.     chain.Flush (TShouldDelete::NoDelete);
  173.     return data;
  174. }
  175.  
  176. template <class Node, class T>
  177. T* TBPlusTreeBase<Node, T>::Search (
  178.     CompFunc compare,
  179.     void* args) const
  180. {
  181.     Node::TNodeBase* node = root;
  182.     while (node)
  183.     {
  184.         T* data = static_cast<Node*> (node)->DataPtr();
  185.         int c = compare (*data, args);
  186.         if (c == 0)
  187.             return data;
  188.  
  189.         node = c < 0 ? node->Left() : node->Right();
  190.     }
  191.     return 0;
  192. }
  193.  
  194. template <class Node, class T>
  195. int TBPlusTreeBase<Node, T>::AddNode (
  196.     Node* newNode,
  197.     TChain& chain)
  198. {
  199. #if defined(_DEBUG_B_TREE_)
  200.     CHECK (CheckTree());
  201. #endif
  202.  
  203.     if (root)
  204.     {
  205.         Node* parent = static_cast<Node*> (*chain.Top());
  206.         if (*newNode->DataPtr() < *parent->DataPtr())
  207.         {
  208.             parent->Left() = newNode;
  209.             chain.Push (&parent->Left());
  210.         }
  211.         else
  212.         {
  213.             parent->Right() = newNode;
  214.             chain.Push (&parent->Right());
  215.         }
  216.         BalanceAdd (chain);
  217.     }
  218.     else
  219.         root = newNode;
  220.  
  221.     itemCnt += 1;
  222. #if defined(_DEBUG_B_TREE_)
  223. #if _DEBUG_B_TREE_ > 1
  224.     CHECK (CheckTree());
  225. #endif
  226. #endif
  227.     return 1;
  228. }
  229.  
  230. template <class Node, class T>
  231. void TBPlusTreeBase<Node, T>::DetachNode (
  232.     Node* node,
  233.     TChain& chain)
  234. {
  235.     Node* child = static_cast<Node*> (node->Left() ? node->Left():node->Right());
  236.     Node*& childPtr = static_cast<Node*> (*chain.Pop());
  237.     if (!chain.IsEmpty())
  238.     {
  239.         Node::TNodeBase** parent = chain.Pop();
  240.         (*parent)->Balance() = static_cast<TBalance> ((*parent)->Balance() -
  241.             ((*parent)->Left() == node ? LeftBalance : RightBalance));
  242.  
  243.         childPtr = child;
  244.         (*parent)->Balance (*parent);
  245.         child = static_cast<Node*> (*parent);
  246.         while (child->Balance() == Balanced && !chain.IsEmpty())
  247.         {
  248.             parent = chain.Pop();
  249.             (*parent)->BalanceDetach (child, *parent);
  250.             child = static_cast<Node*> (*parent);
  251.         }
  252.     }
  253.     else
  254.         childPtr = child;
  255.  
  256.     itemCnt -= 1;
  257. #if defined(_DEBUG_B_TREE_)
  258. #if _DEBUG_B_TREE_ > 1
  259.     CHECK (CheckTree());
  260. #endif
  261. #endif
  262. }
  263.  
  264. template <class Node, class T>
  265. Node* TBPlusTreeBase<Node, T>::FindNode (
  266.     const T* t) const
  267. {
  268. #if defined(_DEBUG_B_TREE_)
  269. #if _DEBUG_B_TREE_ > 1
  270.     CHECK (CheckTree());
  271. #endif
  272. #endif
  273.     Node* node = static_cast<Node*> (root);
  274.     while (node)
  275.     {
  276.         if (*node->DataPtr() == *t)
  277.             return node;
  278.  
  279.         node = static_cast<Node*> (*t < *node->DataPtr() ? node->Left() :
  280.             node->Right());
  281.     }
  282.     return 0;
  283. }
  284.  
  285. template <class Node, class T>
  286. Node* TBPlusTreeBase<Node, T>::FindNode (
  287.     const T* t,
  288.     TChain& chain)
  289. {
  290. #if defined(_DEBUG_B_TREE_)
  291. #if _DEBUG_B_TREE_ > 1
  292.     CHECK (CheckTree());
  293. #endif
  294. #endif
  295.     Node::TNodeBase** nodePtr = &root;
  296.     Node* node = static_cast<Node*> (*nodePtr);
  297.     while (node)
  298.     {
  299.         chain.Push (nodePtr);
  300.         if (*node->DataPtr() == *t)
  301.             return node;
  302.  
  303.         nodePtr = (*t < *node->DataPtr() ? &node->Left() : &node->Right());
  304.         node = static_cast<Node*> (*nodePtr);
  305.     }
  306.     return 0;
  307. }
  308.  
  309. template <class Node, class T>
  310. void TBPlusTreeBase<Node, T>::BalanceAdd (
  311.     TChain& chain)
  312. {
  313.     Node::TNodeBase* child = *chain.Pop();
  314.     do {
  315.         Node::TNodeBase*& node = *chain.Pop();
  316.         if (node->BalanceAdd (child, node))
  317.             break;
  318.  
  319.         child = node;
  320.     }
  321.     while (child->Balance() && !chain.IsEmpty());
  322. }
  323.  
  324. #if __DEBUG > 0
  325. #if defined(_DEBUG_B_TREE_)
  326. template <class Node, class T>
  327. int TBPlusTreeBase<Node, T>::CheckTree ()
  328. {
  329.     int height;
  330.     if (root)
  331.     {
  332.         unsigned cnt = root->CheckNode (height);
  333.         CHECK (cnt == itemCnt);
  334. #if _DEBUG_B_TREE_ > 1
  335.         const T* minValue = 0;
  336.         const T* maxValue = 0;
  337.         CheckValues (static_cast<Node&> (*root), minValue, maxValue);
  338. #endif
  339.     }
  340.     return 1;
  341. }
  342.  
  343. template <class Node, class T>
  344. void TBPlusTreeBase<Node, T>::CheckValues (
  345.     Node& node,
  346.     const T*& minValue,
  347.     const T*& maxValue)
  348. {
  349.     const T* value;
  350.     minValue = maxValue = node.DataPtr();
  351.     if (node.Left())
  352.     {
  353.         CheckValues (static_cast<Node&> (node.LeftNode()), minValue, value);
  354.         CHECK (*value < *node.DataPtr());
  355.     }
  356.  
  357.     if (node.Right())
  358.     {
  359.         CheckValues (static_cast<Node&> (node.RightNode()), value, maxValue);
  360.         CHECK (*node.DataPtr() < *value);
  361.     }
  362. }
  363. #endif
  364. #endif
  365.  
  366. /*
  367.  * Template TBPlusTreeIteratorBase, iterator for template TBPlusTreeBase
  368.  */
  369. template <class Node, class T> class TBPlusTreeIteratorBase
  370. {
  371. public:
  372.     TBPlusTreeIteratorBase (const TBPlusTreeBase<Node, T>& t) :
  373.         tree (const_cast<TBPlusTreeBase<Node, T>&> (t))
  374.         {
  375.         first = lowerLimit = upperLimit = 0;
  376.         if (tree.root)
  377.             {
  378.             lowerLimit = tree.root->WalkLeft();
  379.             upperLimit = tree.root->WalkRight();
  380.             first = lowerLimit;
  381.             }
  382.         Restart();
  383.         }
  384.  
  385.     TBPlusTreeIteratorBase (const TBPlusTreeBase<Node, T>& t, const T* start,
  386.         const T* end) :
  387.         tree (const_cast<TBPlusTreeBase<Node, T>&> (t))
  388.         {
  389.         Restart (start, end);
  390.         }
  391.  
  392.     operator int () const
  393.         {
  394.         return !chain.IsEmpty();
  395.         }
  396.  
  397.     const T* Current (void) const
  398.         {
  399.         PRECONDITION (!chain.IsEmpty());
  400.         return GetCurrent();
  401.         }
  402.  
  403.     const T* operator ++ (int)
  404.         {
  405.         const T* t = Current();
  406.         Next();
  407.         return t;
  408.         }
  409.  
  410.     const T* operator ++ ()
  411.         {
  412.         Next();
  413.         return Current();
  414.         }
  415.  
  416.     const T* operator -- (int)
  417.         {
  418.         const T* t = Current();
  419.         Previous();
  420.         return t;
  421.         }
  422.  
  423.     const T* operator -- ()
  424.         {
  425.         Previous();
  426.         return Current();
  427.         }
  428.  
  429.     void Restart (void);
  430.     void Restart (const T*, const T*);
  431.  
  432. private:
  433.     T* GetCurrent (void) const
  434.         {
  435.         return static_cast<Node&> (**chain.Top()).DataPtr();
  436.         }
  437.  
  438.     void Next (void);
  439.     void Previous (void);
  440.     void FindLimitNode (const T&, int);
  441.  
  442.     typedef TBPlusTreeBase<Node, T> Tree;
  443.  
  444.     Tree& tree;
  445.     Tree::TChain chain;
  446.     const Node::TNodeBase* first;
  447.     const Node::TNodeBase* lowerLimit;
  448.     const Node::TNodeBase* upperLimit;
  449. }
  450.  
  451. /*
  452.  * Member functions for class TBPlusTreeIteratorBase
  453.  */
  454. template <class Node, class T>
  455. void TBPlusTreeIteratorBase<Node, T>::Restart (void)
  456. {
  457.     chain.Flush (TShouldDelete::NoDelete);
  458.     if (lowerLimit && upperLimit)
  459.         tree.FindNode (static_cast<const Node&> (*first).DataPtr(), chain);
  460. }
  461.  
  462. template <class Node, class T>
  463. void TBPlusTreeIteratorBase<Node, T>::Restart (
  464.     const T* start,
  465.     const T* end)
  466. {
  467.     chain.Flush (TShouldDelete::NoDelete);
  468.     first = lowerLimit = upperLimit = 0;
  469.     if (!tree.root)
  470.         return;
  471.  
  472.     int direction = start && end ? *start < *end : 1;
  473.     if (start)
  474.         FindLimitNode (*start, 0 ^ direction);
  475.     else
  476.     {
  477.         chain.Push (&tree.root);
  478.         tree.root->WalkLeft (chain);
  479.     }
  480.  
  481.     if (!chain.IsEmpty())
  482.         lowerLimit = *chain.Top();
  483.  
  484.     first = lowerLimit;
  485.     chain.Flush (TShouldDelete::NoDelete);
  486.     if (end)
  487.         FindLimitNode (*end, !direction);
  488.     else
  489.     {
  490.         chain.Push (&tree.root);
  491.         tree.root->WalkRight (chain);
  492.     }
  493.  
  494.     if (!chain.IsEmpty())
  495.         upperLimit = *chain.Top();
  496.  
  497.     if (!direction)
  498.     {
  499.         const Node::TNodeBase* t = upperLimit;
  500.         upperLimit = lowerLimit;
  501.         lowerLimit = t;
  502.     }
  503.     Restart();
  504. }
  505.  
  506. template <class Node, class T>
  507. void TBPlusTreeIteratorBase<Node, T>::FindLimitNode (
  508.     const T& t,
  509.     int direction)
  510. {
  511.     if (tree.FindNode (&t, chain) == 0 && ((t < *GetCurrent()) ^ direction))
  512.         if (direction)
  513.             Next();
  514.         else
  515.             Previous();
  516. }
  517.  
  518. template <class Node, class T>
  519. void TBPlusTreeIteratorBase<Node, T>::Next (void)
  520. {
  521.     if (chain.IsEmpty() || *chain.Top() == upperLimit)
  522.         chain.Flush (TShouldDelete::NoDelete);
  523.     else
  524.         Node::Next (chain);
  525. }
  526.  
  527. template <class Node, class T>
  528. void TBPlusTreeIteratorBase<Node, T>::Previous (void)
  529. {
  530.     if (chain.IsEmpty() || *chain.Top() == lowerLimit)
  531.         chain.Flush (TShouldDelete::NoDelete);
  532.     else
  533.         Node::Previous (chain);
  534. }
  535.  
  536. /*
  537.  * Template TBPlusTreeImp. Direct tree
  538.  */
  539. template <class Node, class T> class TBPlusTreeImp :
  540.     public TBPlusTreeBase<Node, T>
  541. {
  542.     typedef TBPlusTreeBase <Node, T> Parent;
  543.  
  544. public:
  545.     TBPlusTreeImp (void) : TBPlusTreeBase<Node, T>()
  546.         {
  547.         }
  548.  
  549.     ~TBPlusTreeImp (void)
  550.         {
  551.         Flush();
  552.         chain.Flush (TShouldDelete::NoDelete);
  553.         }
  554.  
  555.     int HasMember (const T& t) const
  556.         {
  557.         return Parent::HasMember (&t);
  558.         }
  559.  
  560.     int Destroy (const T& t)
  561.         {
  562.         return Detach (t);
  563.         }
  564.  
  565.     int DestroyLast (void)
  566.         {
  567.         return DetachLast();
  568.         }
  569.  
  570.     int DestroyFirst (void)
  571.         {
  572.         return DetachFirst();
  573.         }
  574.  
  575.     T* Find (const T& t) const
  576.         {
  577.         return Parent::Find (&t);
  578.         }
  579.  
  580.     void Flush (void)
  581.         {
  582.         DestroyAllNodes (static_cast<Node*> (root));
  583.         Parent::Flush();
  584.         }
  585.  
  586.     int Add (const T&);
  587.     int Detach (const T&);
  588.     int DetachLast (void);
  589.     int DetachFirst (void);
  590.  
  591. private:
  592.     void Detach (Node*, TChain&);
  593.     void DestroyAllNodes (Node*) const;
  594.  
  595.     TChain chain;
  596. };
  597.  
  598. /*
  599.  * Member function for template TBPlusTreeImp
  600.  */
  601. template <class Node, class T>
  602. int TBPlusTreeImp<Node, T>::Add (
  603.     const T& t)
  604. {
  605.     chain.Flush (TShouldDelete::NoDelete);
  606.     if (FindNode (&t, chain))
  607.         return 0;
  608.  
  609.     return AddNode (new Node (t), chain);
  610. }
  611.  
  612. template <class Node, class T>
  613. int TBPlusTreeImp<Node, T>::Detach (
  614.     const T& t)
  615. {
  616.     chain.Flush (TShouldDelete::NoDelete);
  617.     Node* node = FindNode (&t, chain);
  618.     if (!node)
  619.         return 0;
  620.  
  621.     Detach (node, chain);
  622.     return 1;
  623. }
  624.  
  625. template <class Node, class T>
  626. int TBPlusTreeImp<Node, T>::DetachLast (void)
  627. {
  628.     if (!root)
  629.         return 0;
  630.  
  631.     chain.Flush (TShouldDelete::NoDelete);
  632.     Node* node = static_cast<Node*> (root->WalkRight (chain));
  633.     Detach (node, chain);
  634.     return 1;
  635. }
  636.  
  637. template <class Node, class T>
  638. int TBPlusTreeImp<Node, T>::DetachFirst (void)
  639. {
  640.     if (!root)
  641.         return 0;
  642.  
  643.     chain.Flush (TShouldDelete::NoDelete);
  644.     Node* node = static_cast<Node*> (root->WalkLeft (chain));
  645.     Detach (node, chain);
  646.     return 1;
  647. }
  648.  
  649. template <class Node, class T>
  650. void TBPlusTreeImp<Node, T>::Detach (
  651.     Node* node,
  652.     TChain& chain)
  653. {
  654. #if defined(_DEBUG_B_TREE_)
  655.     CHECK (CheckTree());
  656. #endif
  657.  
  658.     if (node->Left() && node->Right())
  659.     {
  660.         Node* remove;
  661.         if (node->Balance() == RightBalance)
  662.         {
  663.             chain.Push (&node->Right());
  664.             remove = static_cast<Node*> (node->RightNode().WalkLeft (chain));
  665.         }
  666.         else
  667.         {
  668.             chain.Push (&node->Left());
  669.             remove = static_cast<Node*> (node->LeftNode().WalkRight (chain));
  670.         }
  671.  
  672.         node->Data() = remove->Data();
  673.         node = remove;
  674.     }
  675.  
  676.     DetachNode (node, chain);
  677.     delete node;
  678. }
  679.  
  680. template <class Node, class T>
  681. void TBPlusTreeImp<Node, T>::DestroyAllNodes (
  682.     Node* node) const
  683. {
  684.     if (node)
  685.     {
  686.         DestroyAllNodes (static_cast<Node*> (node->Left()));
  687.         DestroyAllNodes (static_cast<Node*> (node->Right()));
  688.         delete node;
  689.     }
  690. }
  691.  
  692. /*
  693.  * Template TBPlusTreeIteratorImp, iterator for template TBPlusTreeImp
  694.  */
  695. template <class Node, class T> class TBPlusTreeIteratorImp :
  696.     public TBPlusTreeIteratorBase<Node, T>
  697. {
  698.     typedef TBPlusTreeIteratorBase<Node, T> Parent;
  699.  
  700.     public:
  701.     TBPlusTreeIteratorImp (const TBPlusTreeImp<Node, T>& t) :
  702.         TBPlusTreeIteratorBase<Node, T> (t)
  703.         {
  704.         }
  705.  
  706.     TBPlusTreeIteratorImp (const TBPlusTreeImp<Node, T>& t, const T& start,
  707.         const T& end) : TBPlusTreeIteratorBase<Node, T> (t, &start, &end)
  708.         {
  709.         }
  710.  
  711.     void Restart (void)
  712.         {
  713.         Parent::Restart();
  714.         }
  715.         
  716.     void Restart (const T& start, const T& end)
  717.         {
  718.         Parent::Restart (&start, &end);
  719.         }
  720.  
  721.     const T& operator ++ (int i)
  722.         {
  723.         return *Parent::operator ++ (i);
  724.         }
  725.  
  726.     const T& operator ++ ()
  727.         {
  728.         return *Parent::operator ++ ();
  729.         }
  730.  
  731.     const T& operator -- (int i)
  732.         {
  733.         return *Parent::operator -- (i);
  734.         }
  735.  
  736.     const T& operator -- ()
  737.         {
  738.         return *Parent::operator -- ();
  739.         }
  740. };
  741.  
  742. /*
  743.  * Template TIBPlusTreeImp. Indirect tree
  744.  */
  745. template <class Node, class T> class TIBPlusTreeImp :
  746.     public TBPlusTreeBase<Node, T>, public TShouldDelete
  747. {
  748.     typedef TBPlusTreeBase <Node, T> Parent;
  749.  
  750. public:
  751.     TIBPlusTreeImp (void) : TBPlusTreeBase<Node, T>()
  752.         {
  753.         }
  754.  
  755.     ~TIBPlusTreeImp (void)
  756.         {
  757.         Flush();
  758.         chain.Flush (TShouldDelete::NoDelete);
  759.         }
  760.  
  761.     int Destroy (T* t)
  762.         {
  763.         return Detach (t, Delete);
  764.         }
  765.  
  766.     int DestroyLast (void)
  767.         {
  768.         return DetachLast (Delete);
  769.         }
  770.  
  771.     int DestroyFirst (void)
  772.         {
  773.         return DetachFirst (Delete);
  774.         }
  775.  
  776.     void Flush (DeleteType dt = DefDelete)
  777.         {
  778.         DestroyAllNodes (static_cast<Node*> (root), DelObj (dt));
  779.         Parent::Flush();
  780.         }
  781.  
  782.     int Add (T*);
  783.     int Detach (T*, DeleteType = NoDelete);
  784.     int DetachLast (DeleteType = NoDelete);
  785.     int DetachFirst (DeleteType = NoDelete);
  786.  
  787. private:
  788.     void Detach (Node*, TChain&, int);
  789.     void DestroyAllNodes (Node*, int) const;
  790.  
  791.     TChain chain;
  792. };
  793.  
  794. /*
  795.  * Member function for template TIBPlusTreeImp
  796.  */
  797. template <class Node, class T>
  798. int TIBPlusTreeImp<Node, T>::Add (
  799.     T* t)
  800. {
  801.     chain.Flush (TShouldDelete::NoDelete);
  802.     if (FindNode (t, chain))
  803.         return 0;
  804.  
  805.     return AddNode (new Node (t), chain);
  806. }
  807.  
  808. template <class Node, class T>
  809. int TIBPlusTreeImp<Node, T>::Detach (
  810.     T* t,
  811.     DeleteType dt)
  812. {
  813.     chain.Flush (TShouldDelete::NoDelete);
  814.     Node* node = FindNode (t, chain);
  815.     if (!node)
  816.         return 0;
  817.  
  818.     Detach (node, chain, DelObj (dt));
  819.     return 1;
  820. }
  821.  
  822. template <class Node, class T>
  823. int TIBPlusTreeImp<Node, T>::DetachLast (
  824.     DeleteType dt)
  825. {
  826.     if (!root)
  827.         return 0;
  828.  
  829.     chain.Flush (TShouldDelete::NoDelete);
  830.     Node* node = static_cast<Node*> (root->WalkRight (chain));
  831.     Detach (node, chain, DelObj (dt));
  832.     return 1;
  833. }
  834.  
  835. template <class Node, class T>
  836. int TIBPlusTreeImp<Node, T>::DetachFirst (
  837.     DeleteType dt)
  838. {
  839.     if (!root)
  840.         return 0;
  841.  
  842.     chain.Flush (TShouldDelete::NoDelete);
  843.     Node* node = static_cast<Node*> (root->WalkLeft (chain));
  844.     Detach (node, chain, DelObj (dt));
  845.     return 1;
  846. }
  847.  
  848. template <class Node, class T>
  849. void TIBPlusTreeImp<Node, T>::Detach (
  850.     Node* node,
  851.     TChain& chain,
  852.     int delObj)
  853. {
  854. #if defined(_DEBUG_B_TREE_)
  855.     CHECK (CheckTree());
  856. #endif
  857.  
  858.     if (delObj)
  859.         delete node->Data();
  860.  
  861.     if (node->Left() && node->Right())
  862.     {
  863.         Node* remove;
  864.         if (node->Balance() == RightBalance)
  865.         {
  866.             chain.Push (&node->Right());
  867.             remove = static_cast<Node*> (node->RightNode().WalkLeft (chain));
  868.         }
  869.         else
  870.         {
  871.             chain.Push (&node->Left());
  872.             remove = static_cast<Node*> (node->LeftNode().WalkRight (chain));
  873.         }
  874.  
  875.         node->Data() = remove->Data();
  876.         node = remove;
  877.     }
  878.  
  879.     DetachNode (node, chain);
  880.     delete node;
  881. }
  882.  
  883. template <class Node, class T>
  884. void TIBPlusTreeImp<Node, T>::DestroyAllNodes (
  885.     Node* node,
  886.     int delObj) const
  887. {
  888.     if (node)
  889.     {
  890.         DestroyAllNodes (static_cast<Node*> (node->Left()), delObj);
  891.         DestroyAllNodes (static_cast<Node*> (node->Right()), delObj);
  892.         if (delObj)
  893.             delete node->Data();
  894.  
  895.         delete node;
  896.     }
  897. }
  898.  
  899. /*
  900.  * Template TIBPlusTreeIteratorImp, iterator for template TIBPlusTreeImp
  901.  */
  902. template <class Node, class T> class TIBPlusTreeIteratorImp :
  903.     public TBPlusTreeIteratorBase<Node, T>
  904. {
  905. public:
  906.     TIBPlusTreeIteratorImp (const TIBPlusTreeImp<Node, T>& t) :
  907.         TBPlusTreeIteratorBase<Node, T> (t)
  908.         {
  909.         }
  910.  
  911.     TIBPlusTreeIteratorImp (const TIBPlusTreeImp<Node, T>& t, const T* start,
  912.         const T* end) : TBPlusTreeIteratorBase<Node, T> (t, start, end)
  913.         {
  914.         }
  915. };
  916.  
  917. /*
  918.  * Template TBPlusTree. Direct tree with allocator
  919.  */
  920. template <class T, class Alloc> class TMBPlusTree :
  921.     public TBPlusTreeImp<TDNode<T, Alloc>, T>
  922. {
  923. public:
  924.     TMBPlusTree (void)
  925.         {
  926.         }
  927. };
  928.  
  929. /*
  930.  * Template TMBPlusTreeIterator, iterator for template TMBPlusTree
  931.  */
  932. template <class T, class Alloc> class TMBPlusTreeIterator :
  933.     public TBPlusTreeIteratorImp<TDNode<T, Alloc>, T>
  934. {
  935. public:
  936.     TMBPlusTreeIterator (const TMBPlusTree<T, Alloc>& t) :
  937.         TBPlusTreeIteratorImp<TDNode<T, Alloc>, T> (t)
  938.         {
  939.         }
  940.  
  941.     TMBPlusTreeIterator (const TMBPlusTree<T, Alloc>& t, const T& start, const T& end) :
  942.         TBPlusTreeIteratorImp<TDNode<T, Alloc>, T> (t, start, end)
  943.         {
  944.         }
  945. };
  946.  
  947. /*
  948.  * Template TIBPlusTree. Indirect tree with allocator
  949.  */
  950. template <class T, class Alloc> class TMIBPlusTree :
  951.     public TIBPlusTreeImp<TINode<T, Alloc>, T>
  952. {
  953. public:
  954.     TMIBPlusTree (void)
  955.         {
  956.         }
  957. };
  958.  
  959. /*
  960.  * Template TIBPlusTreeIterator, iterator for template TIBPlusTree
  961.  */
  962. template <class T, class Alloc> class TMIBPlusTreeIterator :
  963.     public TIBPlusTreeIteratorImp<TINode<T, Alloc>, T>
  964. {
  965. public:
  966.     TMIBPlusTreeIterator (const TMIBPlusTree<T, Alloc>& t) :
  967.         TIBPlusTreeIteratorImp<TINode<T, Alloc>, T> (t)
  968.         {
  969.         }
  970.  
  971.     TMIBPlusTreeIterator (const TMIBPlusTree<T, Alloc>& t, const T* start,
  972.         const T* end) :
  973.         TIBPlusTreeIteratorImp<TINode<T, Alloc>, T> (t, start, end)
  974.         {
  975.         }
  976. };
  977.  
  978. /*
  979.  * Template TBPlusTree. Direct tree
  980.  */
  981. template <class T> class TBPlusTree :
  982.     public TMBPlusTree<T, TStandardAllocator>
  983. {
  984. public:
  985.     TBPlusTree (void)
  986.         {
  987.         }
  988. };
  989.  
  990. /*
  991.  * Template TBPlusTreeIterator, iterator for template TBPlusTree
  992.  */
  993. template <class T> class TBPlusTreeIterator :
  994.     public TMBPlusTreeIterator<T, TStandardAllocator>
  995. {
  996. public:
  997.     TBPlusTreeIterator (const TBPlusTree<T>& t) :
  998.         TMBPlusTreeIterator<T, TStandardAllocator> (t)
  999.         {
  1000.         }
  1001.  
  1002.     TBPlusTreeIterator (const TBPlusTree<T>& t, const T& start, const T& end) :
  1003.         TMBPlusTreeIterator<T, TStandardAllocator> (t, start, end)
  1004.         {
  1005.         }
  1006. };
  1007.  
  1008. /*
  1009.  * Template TIBPlusTree. Indirect tree
  1010.  */
  1011. template <class T> class TIBPlusTree :
  1012.     public TMIBPlusTree<T, TStandardAllocator>
  1013. {
  1014. public:
  1015.     TIBPlusTree (void)
  1016.         {
  1017.         }
  1018. };
  1019.  
  1020. /*
  1021.  * Template TIBPlusTreeIterator, iterator for template TIBPlusTree
  1022.  */
  1023. template <class T> class TIBPlusTreeIterator :
  1024.     public TMIBPlusTreeIterator<T, TStandardAllocator>
  1025. {
  1026. public:
  1027.     TIBPlusTreeIterator (const TIBPlusTree<T>& t) :
  1028.         TMIBPlusTreeIterator<T, TStandardAllocator> (t)
  1029.         {
  1030.         }
  1031.  
  1032.     TIBPlusTreeIterator (const TIBPlusTree<T>& t, const T* start,
  1033.         const T* end) :
  1034.         TMIBPlusTreeIterator<T, TStandardAllocator> (t, start, end)
  1035.         {
  1036.         }
  1037. };
  1038. #endif